/*
 * Partida.h
 *
 * Author: Grupo Nro.
 */

#ifndef PARTIDA_H_
#define PARTIDA_H_

#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <vector>
#include <map>
#include "Constantes.h"
#include "Message.h"
#include "Campania.h"
#include "JugadorConectado.h"
#include "Thread.h"
#include "Mutex.h"

class Game;

class Partida: public Thread {
private:
	int id;
	std::string nombre;
	int estado;
	JugadorConectado* jugador_creador;
	Campania* campaign;
	int level_number;
	std::vector<JugadorConectado*> players;
	Game* current_game;
	std::map<int, int> scores;
	std::string imageFileName;
	Mutex m;

public:
	Partida(int id, std::string nombre, JugadorConectado& jugadorCreador);
	virtual ~Partida();
	int getId();
	std::string getNombre();
	int getCantJugadores();
	int getEstado();
	void setCampaign(Campania& campaign);
	Campania* getCampania();
	int getLevelNumber();
	JugadorConectado* getJugadorCreador();
	void addPlayer(JugadorConectado& player);
	std::vector<JugadorConectado*>& getPlayers();
	// Resetea a 0 el puntaje de todos los jugadores, y envía un mensaje
	// SCORES a cada uno para notificarlo
	void resetScores();
	// Suma los puntos recibidos al puntaje del jugador. Le envía un mensaje
	// SCORES con el nuevo total al jugador.
	void addScore(int player_id, int points);
	int getScore(int player_id);
	std::map<int, int>& getScores();
	void comenzarPartida();
	void run();
	void interrumpirPartida();
	void finalizarPartida();
	// Envía el mensaje al jugador con el id dado
	void notifyPlayer(int player_id, Message msg);
	// Envía el mensaje a todos los jugadores
	void notifyPlayers(Message msg);
	void setId(int id);
	// Agrega un jugador nuevo a la partida. Devuelve true si
	// se alcanzo el minimo de jugadores de la campania
	bool agregarJugadorNuevo(JugadorConectado* jc);
	// busca al jugador que creo la partida y le pregunta si puede comenzar
	bool solicitarComienzoDePartidaACreadorDePartida();
	 // Indica que el bomberman del jugador con el id dado intentó moverse.
	// Devuelve true si el movimiento puede efectuarse, false en caso contrario
	bool moveUp(int player_id);
	bool moveRight(int player_id);
	bool moveDown(int player_id);
	bool moveLeft(int player_id);
	// Indica que el bomberman del jugador con el id dado intentó plantar una
	// bomba. Devuelve true si puede hacerse, false en caso contrario
	bool plantBomb(int player_id);
	const std::string& getImageFileName() const;
	void setImageFileName(const std::string& imageFileName);
	// Devuelve un string con la representación como tile map del mapa
	std::string& getLevelMapTileRepresentation();
	// Despierta al thread para indicarle que debe cargar el próximo nivel
	void signalStartNextLevel();
	// Devuelve true si un jugador puede unirse a la partida, false en caso contrario
	bool playerCanJoin();

private:
	void setUpGame();
};

#endif /* PARTIDA_H_ */
